package com.irdstudio.tdp.console.api.rest;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.irdstudio.sdk.beans.core.vo.ResponseData;
import com.irdstudio.tdp.console.constant.Constants;
import com.irdstudio.tdp.console.dao.domain.OsrvArrangeVar;
import com.irdstudio.tdp.console.service.facade.OsrvArrangeTableService;
import com.irdstudio.tdp.console.service.facade.OsrvArrangeVarService;
import com.irdstudio.tdp.console.service.facade.OsrvNodeInfoService;
import com.irdstudio.tdp.console.service.vo.AppModelInfo2VO;
import com.irdstudio.tdp.console.service.vo.OsrvArrangeVarVO;
import com.irdstudio.tdp.console.service.vo.OsrvNodeInfoVO;
import com.irdstudio.tdp.console.dao.domain.AppModelInfo;
import com.irdstudio.tdp.console.dao.domain.IsrvInoutInfo;
import com.irdstudio.tdp.console.service.facade.IsrvInoutInfoService;
import com.irdstudio.tdp.console.utils.ExcelUtil;
import com.irdstudio.sdk.beans.core.util.DateUtility;
import com.irdstudio.sdk.beans.core.util.TimeUtil;
import com.irdstudio.sdk.beans.core.util.UUIDUtil;
import com.irdstudio.sdk.ssm.vo.UserInfo;
import com.irdstudio.sdk.ssm.web.AbstractController;
import com.irdstudio.tdp.console.service.facade.AppModelInfoService;
import com.irdstudio.tdp.console.service.vo.AppModelInfoVO;
import com.irdstudio.tdp.executor.core.plugin.gencode.AppModelInfoConstant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;

@RestController
@RequestMapping("/api")
public class AppModelInfoController extends AbstractController {
	
	@Autowired
	@Qualifier("appModelInfoServiceImpl")
	private AppModelInfoService appModelInfoService;

	@Autowired
	@Qualifier("osrvNodeInfoServiceImpl")
	private OsrvNodeInfoService osrvNodeInfoService;

	@Autowired
	@Qualifier("isrvInoutInfoServiceImpl")
	private IsrvInoutInfoService isrvInoutInfoService;

	@Autowired
	@Qualifier("osrvArrangeVarServiceImpl")
	private OsrvArrangeVarService osrvArrangeVarService;


	/**
	 * 列表数据查询
	 * @return
	 */
	@RequestMapping(value="/app/model/infos", method=RequestMethod.POST)
	public @ResponseBody
	ResponseData<List<AppModelInfoVO>> queryAppModelInfoAll(AppModelInfoVO vo) {
		List<AppModelInfoVO> outputVo = appModelInfoService.queryAllOwner(vo);
		return getResponseData(outputVo);
		
	}

	/**
	 * 列表数据查询
	 * @return
	 */
	@RequestMapping(value="/app/model/infos2", method=RequestMethod.POST)
	public @ResponseBody ResponseData<List<AppModelInfo2VO>> queryAppModelInfoAll2(@RequestBody AppModelInfoVO vo) {
		List<AppModelInfo2VO> outputVo = appModelInfoService.queryAllOwner2(vo);
		return getResponseData(outputVo);

	}
	
	/**
	 * 根据主键查询详情
	 * @return
	 */
	@RequestMapping(value="/app/model/info/{appModelId}", method=RequestMethod.GET)
	public @ResponseBody ResponseData<AppModelInfoVO> queryByPk(@PathVariable("appModelId") String appModelId) {		
		AppModelInfoVO inVo = new AppModelInfoVO();
		inVo.setAppModelId(appModelId);
		AppModelInfoVO outputVo = appModelInfoService.queryByPk(inVo);
		return getResponseData(outputVo);
	}
	
	/**
	 * 根据主键删除信息
	 * @param appModelInfo
	 * @return
	 */
	@RequestMapping(value="/app/model/info", method=RequestMethod.DELETE)
	public @ResponseBody ResponseData<Integer> deleteByPk(@RequestBody AppModelInfoVO inAppModelInfoVo) {		
		int outputVo = appModelInfoService.deleteByPk(inAppModelInfoVo);
		return getResponseData(outputVo);
		
	}
	
	/**
	 * 根据主键更新信息
	 * @param inAppModelInfoVo
	 * @return
	 */
	@RequestMapping(value="/app/model/info", method=RequestMethod.PUT)
	public @ResponseBody ResponseData<Integer> updateByPk(@RequestBody AppModelInfoVO inAppModelInfoVo) {		
		int outputVo = appModelInfoService.updateByPk(inAppModelInfoVo);
		return getResponseData(outputVo);
		
	}
	
	/**
	 * 新增数据
	 * @param inAppModelInfoVo
	 * @return
	 */
	@RequestMapping(value="/app/model/info", method=RequestMethod.POST)
	public @ResponseBody ResponseData<String> insertAppModelInfo(@RequestBody AppModelInfoVO inAppModelInfoVo) {
		setUserInfoToVO(inAppModelInfoVo);
		String appModelId=UUIDUtil.getUUID();
		inAppModelInfoVo.setCreateUser(inAppModelInfoVo.getLoginUserId());
		inAppModelInfoVo.setCreateTime(TimeUtil.getCurrentDateTime());
		inAppModelInfoVo.setAppModelId(appModelId);
		int outputVo = appModelInfoService.insertAppModelInfo(inAppModelInfoVo);
		if (inAppModelInfoVo.getAppModelCatalog().equals("A01")) {
			// 为外服服务时 默认需创建外服入参、外服出参两个标签
			OsrvNodeInfoVO input = new OsrvNodeInfoVO();
			input.setAppModelId(inAppModelInfoVo.getAppModelId());
			input.setNodeType("00"); // 外服输入
			input.setNodeName("外服入参");
			input.setNodeId(UUIDUtil.getUUID());
			input.setX(120);
			input.setY(50);
			osrvNodeInfoService.insertOsrvNodeInfo(input);
			OsrvNodeInfoVO output = new OsrvNodeInfoVO();
			output.setAppModelId(inAppModelInfoVo.getAppModelId());
			output.setNodeType("99"); // 外服输入
			output.setNodeName("外服出参");
			output.setNodeId(UUIDUtil.getUUID());
			output.setX(120);
			output.setY(480);
			osrvNodeInfoService.insertOsrvNodeInfo(output);

			// 创建领域服务编排变量
			OsrvArrangeVarVO inputVar = new OsrvArrangeVarVO(); // 服务入参
			inputVar.setVarId(UUIDUtil.getUUID());
			inputVar.setAppModelId(appModelId);
			inputVar.setVarName(Constants.VarType.Input.getName());
			inputVar.setVarType(Constants.VarType.Input.getCode());
			inputVar.setVarModelId(inAppModelInfoVo.getAppId());
			inputVar.setVarTableRowNo(1);
			osrvArrangeVarService.insertOsrvArrangeVar(inputVar);
			OsrvArrangeVarVO outputVar = new OsrvArrangeVarVO(); // 服务出参
			outputVar.setVarId(UUIDUtil.getUUID());
			outputVar.setAppModelId(appModelId);
			outputVar.setVarName(Constants.VarType.Output.getName());
			outputVar.setVarType(Constants.VarType.Output.getCode());
			outputVar.setVarModelId(inAppModelInfoVo.getAppId());
			outputVar.setVarTableRowNo(1);
			osrvArrangeVarService.insertOsrvArrangeVar(outputVar);
			OsrvArrangeVarVO var = new OsrvArrangeVarVO(); //  领域变量
			var.setVarId(UUIDUtil.getUUID());
			var.setAppModelId(appModelId);
			var.setVarName(Constants.VarType.Var.getName());
			var.setVarType(Constants.VarType.Var.getCode());
			var.setVarModelId(inAppModelInfoVo.getAppId());
			var.setVarTableRowNo(1);
			osrvArrangeVarService.insertOsrvArrangeVar(var);
		}
		if(outputVo==1){
			return getResponseData(appModelId);
		}
		return getResponseData(null);
	}

	/**
	 * 根据app_model_id 查询外部服务相关信息
	 *
	 * @param appModelId
	 * @return
	 * @oaram appId
	 */
	@GetMapping(value = "/app/model/info/external/{appModelId}/{appId}")
	public @ResponseBody
	ResponseData<Map<String, Object>> queryExternalService(@PathVariable("appId") String appId, @PathVariable("appModelId") String appModelId) {
		try {
			Map<String, Object> result = appModelInfoService.queryExternalServiceFlowChart(appId, appModelId);
			return getResponseData(result);
		} catch (Exception e) {
			logger.error("查询外部服务相关信息异常 appId {} appModelId {}", appId, appModelId, e);
			ResponseData re = getResponseData(null);
			re.setMessage(e.getMessage());
			return re;
		}
	}

	/**
	 * 根据app_model_id 保存流程数据
	 *
	 * @param appModelId
	 * @return
	 * @oaram appId
	 */
	@PostMapping(value = "/app/model/info/external/{appId}")
	public @ResponseBody
	ResponseData<Boolean> saveExternalService(@PathVariable("appId") String appId, @RequestBody Map<String, Object> flowData) {
		try {
			boolean flag = appModelInfoService.saveExternalServiceFlowChart(appId, flowData);
			return getResponseData(flag);
		} catch (Exception e) {
			logger.error("保存流程数据信息异常 appId {} ", appId, e);
			ResponseData re = getResponseData(null);
			re.setMessage(e.getMessage());
			return re;
		}
	}

	@RequestMapping(value = "/app/model/info/external/upload/{appId}/{packageId}")
	@ResponseBody
	public String upload(@RequestParam("file") MultipartFile file,@PathVariable("appId") String appId,@PathVariable("packageId") String packageId) {
		if (file.isEmpty()) {
			return "上传失败，文件为空，请选择文件";
		}
		try {
//			获取excel数据
//			lists.get(0)为sheet1 ,lists.get(1)为sheet2 ,lists.get(2)为sheet3
			List<List<List<Object>>> lists = ExcelUtil.getUserListByExcel(file.getInputStream(), file.getOriginalFilename());
			List<AppModelInfo> appModelInfos = new ArrayList<>();
			List<IsrvInoutInfo> isrvInInfos = new ArrayList<>();
			UserInfo userInfo = this.getUserInfo();

//			分别将sheet1,sheet2,sheet3的数据放入到对应的list中
			for (int i=0 ;i<lists.get(0).size();i++){
//				sheet1数据
				List<Object> objectList = lists.get(0).get(i);
				AppModelInfo appModelInfo = new AppModelInfo();
				String AppModeId = UUIDUtil.getUUID();
				appModelInfo.setAppId(appId);
				appModelInfo.setAppModelId(AppModeId);
				appModelInfo.setAppModelCode(objectList.get(0).toString());
				appModelInfo.setAppModelName(objectList.get(1).toString());
				appModelInfo.setAppModelCatalog("A01");
				appModelInfo.setAppModelType("A0101");
				appModelInfo.setPackageId(packageId);
				appModelInfo.setTableModelId("");
				appModelInfo.setTableModelCode("");
				appModelInfo.setTableModelName("");
				appModelInfo.setCreateUser(userInfo.getUserId());
				appModelInfo.setCreateTime(DateUtility.getCurrDateTime());
				appModelInfo.setLastUpdateUser("");
				appModelInfo.setLastUpdateTime("");
				appModelInfos.add(appModelInfo);

//				sheet2数据
				List<Object> in = lists.get(1).get(i);
				IsrvInoutInfo isrvInoutInfo = new IsrvInoutInfo();
				isrvInoutInfo.setRecordKeyid(UUIDUtil.getUUID());
				isrvInoutInfo.setAppModelId(AppModeId);
				isrvInoutInfo.setParamFieldCode(in.get(0).toString());
				isrvInoutInfo.setParamFieldType(in.get(1).toString());
				isrvInoutInfo.setParamFieldName(in.get(2).toString());
				isrvInoutInfo.setIoType("I");
				isrvInoutInfo.setMustNeed("");
				isrvInInfos.add(isrvInoutInfo);
//				sheet3数据
				List<Object> out = lists.get(2).get(i);
				IsrvInoutInfo isrvInoutInfo1 = new IsrvInoutInfo();
				isrvInoutInfo1.setRecordKeyid(UUIDUtil.getUUID());
				isrvInoutInfo1.setAppModelId(AppModeId);
				isrvInoutInfo1.setParamFieldCode(out.get(0).toString());
				isrvInoutInfo1.setParamFieldType(out.get(1).toString());
				isrvInoutInfo1.setParamFieldName(out.get(2).toString());
				isrvInoutInfo1.setIoType("O");
				isrvInoutInfo1.setMustNeed("");
				isrvInInfos.add(isrvInoutInfo1);
			}
			//批量插入数据
			appModelInfoService.insertAppModelInfos(appModelInfos);
			isrvInoutInfoService.insertIsrvInoutInfos(isrvInInfos);
		} catch (Exception e) {
			e.printStackTrace();
		}

		return "导入excel数据成功";
	}

	/**
	 * 导出excel文档
	 * @return
	 */
	@RequestMapping(value="/app/model/info/external/excel/{appId}", method= RequestMethod.GET)
	public @ResponseBody void generateExcelDocuments(@PathVariable("appId")String appId, HttpServletResponse response) throws Exception {
		appModelInfoService.generateExcelDocuments(appId,response);
	}

	/**
	 * 初始化单表的业务模型
	 *
	 * @return
	 */
	@PostMapping(value = "/sd/app/init/create/{appModelCatalog}/{appId}")
	public @ResponseBody
	ResponseData<Boolean> initBizModel(@PathVariable("appId") String appId,
									   @PathVariable("appModelCatalog") String appModelCatalog,
									   @RequestBody AppModelInfoVO inAppModelInfoVo) {
		boolean flag = false;
		setUserInfoToVO(inAppModelInfoVo);
		inAppModelInfoVo.setCreateUser(inAppModelInfoVo.getLoginUserId());
		inAppModelInfoVo.setCreateTime(TimeUtil.getCurrentDateTime());
		inAppModelInfoVo.setAppModelId(UUIDUtil.getUUID());
		if (appModelCatalog.equals(AppModelInfoConstant.AppModelCatalogEnum.APP_MODEL_CATALOG_I01.getCode())) {
			// 数据服务自定义新增 初始化
			flag = appModelInfoService.initDataServiceModel(appId, appId, inAppModelInfoVo);
		}

		return getResponseData(flag);
	}
}
